<!--
 * @Author: wei_jt@ecidi.com
 * @Date: 2019-11-09 10:32:49
 * @LastEditors: wei_jt@ecidi.com
 * @LastEditTime: 2021-12-29 09:20:02
 * @Description: 应用配置
 -->
<template>
  <div class="body">
    <div class="top">
      <div>
        <p class="firstTitle">背景:</p>
        <span
          >传统的关系型数据库在存储大数据量时需要进行分库分表，但是分库分表后又很难实现复杂查询的需求，所以这个时候就需要引入异构数据源来做OLAP的场景。</span
        >
        <p class="firstTitle">搜索系统的目标：</p>
        <p>海量请求：支持亿级请求</p>
        <p>秒级响应：复杂查询秒级内出结果</p>
        <p>实时搜索：数据被修改后，能实时搜索到最新数据</p>
        <p style="width: 100%; font-weight: bold; font-size: 16px">总体架构:</p>
        <p>1、海量请求和秒级响应</p>
        <span
          >使用ElasticSearch来实现这个目标，是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎，基于RESTful
          web接口。Elasticsearch是用Java开发的，并作为Apache许可条款下的开放源码发布，
          是当前流行的企业级搜索引擎。能够达到实时搜索，稳定，可靠，快速，安装使用方便。</span
        >
      </div>
      <div>
        <img
          src="@/assets/img/systemDemonstration/full_text.png"
          alt="sidemenu"
        />
      </div>
    </div>
    <div style="padding: 0 1%">
      <p style="margin-top: 0">2、实时增量同步</p>
      <span
        >阿里的开源项目Canal，就是用来解决这个问题的，Canal项目利用了MySQL数据库主从同步的原理，将Canal
        Server模拟成一台需要同步的从库，从而让主库将binlog日志流发送到Canal
        Server接口。Canal项目对binlog日志的解析进行了封装，我们可以直接得到解析后的数据，而不需要理会binlog的日志格式。而且Canal项目整合了zookeeper，
        、整体实现了高可用，可伸缩性强。</span
      >
      <p>3、MQ</p>
      <span
        >Canal收集的binlog数据支持直接发送到MQ中目前支持RocketMQ和Kafka和Rabbit，用于削峰填谷。</span
      >
      <p>4、Adapter</p>
      <span
        >Canal提供各种Adapter组件用于binlog转换，这里利用Adapter实现消费MQ的binlog信息自动转换为索引数据存到ES中。</span
      >
      <p>5、搜索服务与组件</p>
      <span
        >es客户端的api比较复杂难懂，凤翎通过通用的搜索服务对外提供restful的API接口供业务系统使用，并开发负责操作ES实现高亮、分页、权重等特性的组件，屏蔽底层的复杂性。</span
      >
    </div>

    <div class="pageStyle">
      <fks-query-page
        v-loading="loading"
        :data="tableData"
        :total="total"
        :page-size.sync="pageSize"
        :current-page.sync="pageNo"
        layout="total, sizes, prev, pager, next, jumper"
        :page-sizes="[20, 50, 100]"
        :element-loading-text="LANG.LOADING"
        :table-name="LANG.LOG_INTERFACE_LIST"
        @query="getData"
      >
        <template slot="singleSearch">
          <div class="single-searchBox">
            <fks-input
              v-model="searchValue"
              size
              :placeholder="LANG.FTR"
              class="single-searchBox-item"
              clearable
              maxlength="50"
              @clear="search"
              @keyup.enter.native="search"
            >
              <fks-button
                slot="append"
                icon="fks-icon-search"
                @click="search"
              />
            </fks-input>
          </div>
        </template>
        <template>
          <fks-table-column type="index" align="center" label="#">
            <template slot-scope="scope">
              {{ scope.$index + 1 }}
            </template>
          </fks-table-column>
          <fks-table-column
            prop="request_uri"
            :label="LANG.LOG_INTERFACE"
            header-align="center"
            align="left"
            min-width="130px"
          >
            <template slot-scope="scope">
              <span v-html="scope.row.request_uri" />
            </template>
          </fks-table-column>
          <fks-table-column
            prop="service_name"
            :label="LANG.LOG_SERVICE"
            header-align="center"
            align="left"
            min-width="130px"
          >
            <template slot-scope="scope">
              <span v-html="scope.row.service_name" />
            </template>
          </fks-table-column>
          <fks-table-column
            prop="title"
            :label="LANG.INTERFACE_INTERPRETATION"
            header-align="center"
            align="left"
            min-width="180px"
          >
            <template slot-scope="scope">
              <span v-html="scope.row.title" />
            </template>
          </fks-table-column>
          <fks-table-column
            prop="method_type"
            :label="LANG.REQUEST_TYPE"
            width="60"
          >
            <template slot-scope="scope">
              <span v-html="scope.row.method_type" />
            </template>
          </fks-table-column>
          <fks-table-column prop="user_fullname" :label="LANG.USER_FULL_NAME">
            <template slot-scope="scope">
              <span v-html="scope.row.user_fullname" />
            </template>
          </fks-table-column>
          <fks-table-column prop="user_name" :label="LANG.USERNAME">
            <template slot-scope="scope">
              <span v-html="scope.row.user_name" />
            </template>
          </fks-table-column>
          <fks-table-column
            prop="create_time"
            :label="LANG.LOG_TIME"
            min-width="180px"
          >
            <template slot-scope="scope">
              <span v-html="scope.row.create_time" />
            </template>
          </fks-table-column>
        </template>
      </fks-query-page>
    </div>
  </div>
</template>

<script>
import { getData } from './api'
export default {
  name: 'FTR',
  data() {
    return {
      searchValue: '',
      pageSize: 20,
      pageNo: 1,
      total: 0,
      tableData: [],
      loading: false
    }
  },
  mounted() {
    this.getData()
  },
  methods: {
    //初始化数据
    getData() {
      this.aTableData = []
      this.loading = true
      let params = {
        filterField: '',
        filterValue: '',
        indexNames: 'fawkes_sys_api_log',
        isHighlighter: true,
        order: 'DESC',
        pageNo: this.pageNo,
        pageSize: this.pageSize,
        routing: '',
        searchValue: this.searchValue
          ? `request_uri:${this.searchValue} OR service_name:${this.searchValue} OR title:${this.searchValue}  OR method_type:${this.searchValue} OR  user_fullname:${this.searchValue} OR user_name:${this.searchValue} OR create_time:${this.searchValue} `
          : '',
        sort: '_score'
      }
      this.getDataList(params)
    },
    //清空搜索内容回调
    search() {
      this.pageNo = 1
      this.getData()
    },
    //获取列表数据
    getDataList(params) {
      getData(params)
        .then((res) => {
          if (res.data) {
            this.tableData = res.data.list
            this.total = res.data.total
          }
          this.loading = false
        })
        .catch((err) => {
          this.loading = false
        })
    }
  }
}
</script>
<style scoped lang="scss">
.body {
  width: 100%;
  height: 100%;
  padding: 20px;
  padding-bottom: 10px;
  overflow-y: auto;
  background-color: white !important;
}

.top {
  display: flex;
  padding: 1% 1% 0;
}

.firstTitle {
  width: 100%;
  font-weight: bold;
  font-size: 16px;
}

.pageStyle {
  width: 100%;
  height: 100%;
}
</style>